package com.wswy.wzcx.jpush;

import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.che.common.map.LocationModel;
import com.che.libcommon.api.ApiOptionalResultObserver;
import com.che.libcommon.api.BaseResult;
import com.wswy.wzcx.AppContext;
import com.wswy.wzcx.api.Api;
import com.wswy.wzcx.jpush.IPushOperator.OnPushOperatorCallback;
import com.wswy.wzcx.model.DataCenter;
import com.wswy.wzcx.module.LocManager;
import com.wswy.wzcx.module.WeatherManager;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

public class PushTagManager {

  private static final String TAG = "PushTagManager";

  private static final String TAG_NO_LOGIN = "nologin";
  private static final String TAG_CITY = "city_";
  private static final String TAG_NO_CAR = "nocar";

  private static final String TAG_NO_LICENSE = "nolicense";

  private static final int MSG_NEXT = 10;
  private static final int CLEAN_TAGS = 21;
  private static final int UPDATE_TAGS = 31;

  private Set<String> cacheTags = new HashSet<>();

  private NotificationHandler handler;


  private TagConditions tagConditions = new TagConditions();


  private Handler msgHandler;

  private LinkedList<Integer> msgList =new LinkedList<>();

  private AtomicBoolean isProcessing = new AtomicBoolean(false);

  PushTagManager(NotificationHandler handler){
    this.handler = handler;



    msgHandler=new Handler(){
      @Override
      public void handleMessage(Message msg) {
        super.handleMessage(msg);

        if(msg.what == MSG_NEXT){
          if(!msgList.isEmpty()){
            innerHandle(msgList.pollFirst());
          }
        }
      }
    };
    //msgList.add(CLEAN_TAGS);

    msgHandler.sendEmptyMessageDelayed(MSG_NEXT,5000);

  }

  private void innerHandle(int type){
    switch (type){
      case CLEAN_TAGS:
        cleanTags();
        break;
      case UPDATE_TAGS:
        innerUpdateTags();
        break;
    }
  }

  private void next(){
    isProcessing.set(false);

    msgHandler.sendEmptyMessage(MSG_NEXT);
  }

  private void cleanTags(){

    isProcessing.set(true);

    handler.cleanTags(new OnPushOperatorCallback<Boolean>() {
      @Override
      public void onOperatorCallback(Boolean aBoolean) {
        next();
      }
    });
  }


  private void innerUpdateTags(){


    if(tagConditions.isUpdating){
      return;
    }


    LocationModel currentLocation = LocManager.getInstance()
        .getCurrentLocation();

    double lon = 0;
    double lat = 0;
    boolean isLogin = DataCenter.get().hasLogin();

    if(currentLocation != null){
      lon = currentLocation.longitude;
      lat = currentLocation.latitude;
    }

    String city = LocManager.getInstance().getDisplayCityName();

    //如果tag条件没变，不需要更新
    if(tagConditions.compare(lon,lat,isLogin,city)){
      return;
    }

    //保存当前tag条件参数
    tagConditions.lon = lon;
    tagConditions.lat = lat;
    tagConditions.isLogin = isLogin;
    tagConditions.city = city;

    tagConditions.isUpdating = true;

    Api.get().getPushTags(lon,lat,city).subscribe(new ApiOptionalResultObserver<Map<String,String>>(){

      @Override
      protected void onApiResult(@Nullable Map<String, String> map) {
        tagConditions.isUpdating = false;
        if(map != null){

          Set<String> tags = new HashSet<>(map.values());

          setTags(tags);

        }

      }

      @Override
      protected void onApiError(@Nullable BaseResult result) {
        tagConditions.isUpdating = false;
      }
    });

  }

  public void updateTags(){

    msgList.remove(Integer.valueOf(UPDATE_TAGS));

    msgList.addLast(UPDATE_TAGS);

    if(!isProcessing.get()){
      msgHandler.sendEmptyMessage(MSG_NEXT);
    }

  }


  private void setTags(Set<String> tags){

    isProcessing.set(true);

    handler.setTags(tags, new OnPushOperatorCallback<Set<String>>() {
      @Override
      public void onOperatorCallback(Set<String> strings) {

        next();

      }
    });

  }


  private static class TagConditions{
    double lon;
    double lat;
    boolean isLogin = false;
    String city;

    boolean compare(double lon,double lat,boolean isLogin,String city){
      return this.lon == lon && this.lat == lat && this.isLogin == isLogin && TextUtils.equals(city,this.city);
    }

    boolean isUpdating = false;
  }



  /**
   * 未登录
   * @param add true添加,false移除
   */
  private void operaNoLogin(boolean add){


    if(add){

     if(cacheTags.contains(TAG_NO_LOGIN)){
       return;
     }

      Set<String> tags = new HashSet<>(cacheTags);
      tags.remove(TAG_NO_CAR);
      tags.remove(TAG_NO_LICENSE);

      tags.add(TAG_NO_LOGIN);

      handler.setTags(tags, new OnPushOperatorCallback<Set<String>>() {
        @Override
        public void onOperatorCallback(Set<String> strings) {
          cacheTags.clear();
          cacheTags.addAll(strings);
        }
      });

    } else {

      if(!cacheTags.contains(TAG_NO_LOGIN)){
        return;
      }

      handler.deleteTags(Collections.singleton(TAG_NO_LOGIN),
          new OnPushOperatorCallback<Set<String>>() {
            @Override
            public void onOperatorCallback(Set<String> strings) {

              cacheTags.removeAll(strings);

            }
          });
    }

  }



  private void operaNoCar(boolean add){



    if(add){

      if(cacheTags.contains(TAG_NO_CAR)){
        return;
      }

      cacheTags.add(TAG_NO_CAR);

      handler.addTag(TAG_NO_CAR, new OnPushOperatorCallback<Set<String>>() {
        @Override
        public void onOperatorCallback(Set<String> strings) {

          cacheTags.addAll(strings);

        }
      });
    }else {

      if(!cacheTags.contains(TAG_NO_CAR)){
        return;
      }

      handler.deleteTags(Collections.singleton(TAG_NO_CAR),
          new OnPushOperatorCallback<Set<String>>() {
            @Override
            public void onOperatorCallback(Set<String> strings) {

              cacheTags.removeAll(strings);

            }
          });
    }

  }


  private void setTagCity(final String city){

    if(cacheTags.contains(city)){
      return;
    }


    handler.getTags(new OnPushOperatorCallback<Set<String>>() {
      @Override
      public void onOperatorCallback(Set<String> strings) {

        cacheTags.clear();
        if(strings != null){
          cacheTags.addAll(strings);
        }

        //
        Set<String> newTags = new HashSet<>();
        for (String tag : cacheTags) {
          if(!tag.startsWith(TAG_CITY)){
            newTags.add(tag);
          }
        }

        newTags.add(TAG_CITY+city);
        handler.setTags(newTags, new OnPushOperatorCallback<Set<String>>() {
          @Override
          public void onOperatorCallback(Set<String> strings) {
            cacheTags.clear();
            if(strings != null){
              cacheTags.addAll(strings);
            }
          }
        });

      }
    });

  }


  private void operaNoLicense(boolean add){


    if(add){
      if(cacheTags.contains(TAG_NO_LICENSE)){
        return;
      }

      cacheTags.add(TAG_NO_LICENSE);
      handler.addTag(TAG_NO_LICENSE, new OnPushOperatorCallback<Set<String>>() {
        @Override
        public void onOperatorCallback(Set<String> strings) {
          cacheTags.addAll(strings);
        }
      });

    }else {

      if(!cacheTags.contains(TAG_NO_LICENSE)){
        return;
      }

      handler.deleteTags(Collections.singleton(TAG_NO_LICENSE),
          new OnPushOperatorCallback<Set<String>>() {
            @Override
            public void onOperatorCallback(Set<String> strings) {
              cacheTags.removeAll(strings);
            }
          });
    }


  }


  public void printTags(){
    handler.getTags(new OnPushOperatorCallback<Set<String>>() {
      @Override
      public void onOperatorCallback(Set<String> strings) {
        Log.e(TAG, "onOperatorCallback --> "+strings);
      }
    });
  }



}
